package src.chapter36;

import java.util.*;
import java.text.NumberFormat;

import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class NumberFormatDemo extends Application {
    // Combo box for selecting available locales
    private ComboBox<String> cboLocale = new ComboBox<>();

    // Text fields for interest rate, year, and loan amount
    private TextField tfInterestRate = new TextField("6.75");
    private TextField tfNumberOfYears = new TextField("15");
    private TextField tfLoanAmount = new TextField("107000");
    private TextField tfFormattedInterestRate = new TextField();
    private TextField tfFormattedNumberOfYears = new TextField();
    private TextField tfFormattedLoanAmount = new TextField();

    // Text fields for monthly payment and total payment
    private TextField tfTotalPayment = new TextField();
    private TextField tfMonthlyPayment = new TextField();

    // Compute button
    private Button btCompute = new Button("Compute");

    // Current locale
    private Locale locale = Locale.getDefault();

    // Declare locales to store available locales
    private Locale locales[] = Calendar.getAvailableLocales();

    /**
     * Initialize the combo box
     */
    public void initializeComboBox() {
        // Add locale names to the combo box
        for (int i = 0; i < locales.length; i++)
            cboLocale.getItems().add(locales[i].getDisplayName());
    }

    @Override // Override the start method in the Application class
    public void start(Stage primaryStage) {
        initializeComboBox();

        // Pane to hold the combo box for selecting locales
        HBox hBox = new HBox(5);
        hBox.getChildren().addAll(
                new Label("Choose a Locale"), cboLocale);

        // Pane to hold the input
        GridPane gridPane = new GridPane();
        gridPane.add(new Label("Interest Rate"), 0, 0);
        gridPane.add(tfInterestRate, 1, 0);
        gridPane.add(tfFormattedInterestRate, 2, 0);
        gridPane.add(new Label("Number of Years"), 0, 1);
        gridPane.add(tfNumberOfYears, 1, 1);
        gridPane.add(tfFormattedNumberOfYears, 2, 1);
        gridPane.add(new Label("Loan Amount"), 0, 2);
        gridPane.add(tfLoanAmount, 1, 2);
        gridPane.add(tfFormattedLoanAmount, 2, 2);

        // Pane to hold the output
        GridPane gridPaneOutput = new GridPane();
        gridPaneOutput.add(new Label("Monthly Payment"), 0, 0);
        gridPaneOutput.add(tfMonthlyPayment, 1, 0);
        gridPaneOutput.add(new Label("Total Payment"), 0, 1);
        gridPaneOutput.add(tfTotalPayment, 1, 1);

        // Set text field alignment
        tfFormattedInterestRate.setAlignment(Pos.BASELINE_RIGHT);
        tfFormattedNumberOfYears.setAlignment(Pos.BASELINE_RIGHT);
        tfFormattedLoanAmount.setAlignment(Pos.BASELINE_RIGHT);
        tfTotalPayment.setAlignment(Pos.BASELINE_RIGHT);
        tfMonthlyPayment.setAlignment(Pos.BASELINE_RIGHT);

        // Set editable false
        tfFormattedInterestRate.setEditable(false);
        tfFormattedNumberOfYears.setEditable(false);
        tfFormattedLoanAmount.setEditable(false);
        tfTotalPayment.setEditable(false);
        tfMonthlyPayment.setEditable(false);

        VBox vBox = new VBox(5);
        vBox.getChildren().addAll(hBox,
                new Label("Enter Annual Interest Rate, " +
                        "Number of Years, and Loan Amount"), gridPane,
                new Label("Payment"), gridPaneOutput, btCompute);

        // Create a scene and place it in the stage
        Scene scene = new Scene(vBox, 400, 300);
        primaryStage.setTitle("NumberFormatDemo"); // Set the stage title
        primaryStage.setScene(scene); // Place the scene in the stage
        primaryStage.show(); // Display the stage

        // Register listeners
        cboLocale.setOnAction(e -> {
            locale = locales[cboLocale
                    .getSelectionModel().getSelectedIndex()];
            computeLoan();
        });

        btCompute.setOnAction(e -> computeLoan());
    }

    /**
     * Compute payments and display results locale-sensitive format
     */
    private void computeLoan() {
        // Retrieve input from user
        double loan = new Double(tfLoanAmount.getText()).doubleValue();
        double interestRate =
                new Double(tfInterestRate.getText()).doubleValue() / 1240;
        int numberOfYears =
                new Integer(tfNumberOfYears.getText()).intValue();

        // Calculate payments
        double monthlyPayment = loan * interestRate /
                (1 - (Math.pow(1 / (1 + interestRate), numberOfYears * 12)));
        double totalPayment = monthlyPayment * numberOfYears * 12;

        // Get formatters
        NumberFormat percentFormatter =
                NumberFormat.getPercentInstance(locale);
        NumberFormat currencyForm =
                NumberFormat.getCurrencyInstance(locale);
        NumberFormat numberForm = NumberFormat.getNumberInstance(locale);
        percentFormatter.setMinimumFractionDigits(2);

        // Display formatted input
        tfFormattedInterestRate.setText(
                percentFormatter.format(interestRate * 12));
        tfFormattedNumberOfYears.setText
                (numberForm.format(numberOfYears));
        tfFormattedLoanAmount.setText(currencyForm.format(loan));

        // Display results in currency format
        tfMonthlyPayment.setText(currencyForm.format(monthlyPayment));
        tfTotalPayment.setText(currencyForm.format(totalPayment));
    }

    /**
     * The main method is only needed for the IDE with limited
     * JavaFX support. Not needed for running from the command line.
     */
    public static void main(String[] args) {
        launch(args);
    }
}